{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b9ccdcc-4dec-4cb9-a0d9-65a941463150",
   "metadata": {},
   "source": [
    "# Customizing Line Type\n",
    "A new way to specify the linetype:\n",
    "\n",
    "- list, defining the pattern of dashes and gaps used to draw the line: `listOf(dash, gap, ...)`;\n",
    "- list with specified offset: `offset to listOf(dash, gap, ...)`;\n",
    "- string of an even number (up to eight) of hexadecimal digits which give the lengths in consecutive positions in the string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3abd440f-f52b-43b8-90d2-2987fd3e9165",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"21AcEV\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"library\">\n",
       "       if(!window.letsPlotCallQueue) {\n",
       "           window.letsPlotCallQueue = [];\n",
       "       }; \n",
       "       window.letsPlotCall = function(f) {\n",
       "           window.letsPlotCallQueue.push(f);\n",
       "       };\n",
       "       (function() {\n",
       "           var script = document.createElement(\"script\");\n",
       "           script.type = \"text/javascript\";\n",
       "           script.src = \"https://cdn.jsdelivr.net/gh/JetBrains/lets-plot@v4.5.1/js-package/distr/lets-plot.min.js\";\n",
       "           script.onload = function() {\n",
       "               window.letsPlotCall = function(f) {f();};\n",
       "               window.letsPlotCallQueue.forEach(function(f) {f();});\n",
       "               window.letsPlotCallQueue = [];\n",
       "               \n",
       "               \n",
       "           };\n",
       "           script.onerror = function(event) {\n",
       "               window.letsPlotCall = function(f) {};\n",
       "               window.letsPlotCallQueue = [];\n",
       "               var div = document.createElement(\"div\");\n",
       "               div.style.color = 'darkred';\n",
       "               div.textContent = 'Error loading Lets-Plot JS';\n",
       "               document.getElementById(\"21AcEV\").appendChild(div);\n",
       "           };\n",
       "           var e = document.getElementById(\"21AcEV\");\n",
       "           e.appendChild(script);\n",
       "       })();\n",
       "   </script>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%useLatestDescriptors\n",
    "%use lets-plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2aef506b-fd27-4681-aedd-966330dbbfca",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Lets-Plot Kotlin API v.4.9.0. Frontend: Notebook with dynamically loaded JS. Lets-Plot JS v.4.5.1."
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "LetsPlot.getInfo()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "339c39fa-a448-4c25-a7b9-69ed95e2c55b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import org.jetbrains.letsPlot.intern.Plot\n",
    "\n",
    "fun plotLineTypes(linetypes: List<Any>): Plot {\n",
    "    val n = linetypes.size\n",
    "    val data = mapOf(\n",
    "        \"x\" to List(n) { 0 },\n",
    "        \"xend\" to List(n) { 1 },\n",
    "        \"y\" to linetypes,\n",
    "        \"yend\" to linetypes,\n",
    "        \"linetype\" to linetypes\n",
    "    )\n",
    "\n",
    "    return letsPlot(data) +\n",
    "        geomSegment(tooltips = tooltipsNone) {\n",
    "            x = \"x\"; y = \"y\"; xend = \"xend\"; yend = \"yend\"; linetype = \"linetype\"\n",
    "        } +\n",
    "        scaleLinetypeIdentity()\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1fdb580d-983c-47f9-af96-aa2eaf237f96",
   "metadata": {},
   "source": [
    "#### Use Dash Arrays"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "92b9009c-d8a9-4187-9090-d5b189e582ed",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"XMFmqt\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "   \n",
       "   (function() {\n",
       "   // ----------\n",
       "   \n",
       "   var containerDiv = document.getElementById(\"XMFmqt\");\n",
       "   var observer = new ResizeObserver(function(entries) {\n",
       "       for (let entry of entries) {\n",
       "           var width = containerDiv.clientWidth\n",
       "           if (entry.contentBoxSize && width > 0) {\n",
       "           \n",
       "               // Render plot\n",
       "               if (observer) {\n",
       "                   observer.disconnect();\n",
       "                   observer = null;\n",
       "               }\n",
       "\n",
       "               var plotSpec={\n",
       "\"mapping\":{\n",
       "},\n",
       "\"data\":{\n",
       "\"linetype\":[[1.0,1.0],[5.0,5.0],[10.0,5.0],[5.0,[10.0,5.0]],[5.0,10.0,1.0,10.0],[10.0,5.0,1.0,5.0,1.0,5.0]],\n",
       "\"x\":[0.0,0.0,0.0,0.0,0.0,0.0],\n",
       "\"y\":[[1.0,1.0],[5.0,5.0],[10.0,5.0],[5.0,[10.0,5.0]],[5.0,10.0,1.0,10.0],[10.0,5.0,1.0,5.0,1.0,5.0]],\n",
       "\"yend\":[[1.0,1.0],[5.0,5.0],[10.0,5.0],[5.0,[10.0,5.0]],[5.0,10.0,1.0,10.0],[10.0,5.0,1.0,5.0,1.0,5.0]],\n",
       "\"xend\":[1.0,1.0,1.0,1.0,1.0,1.0]\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"linetype\",\n",
       "\"discrete\":true,\n",
       "\"scale_mapper_kind\":\"identity\",\n",
       "\"guide\":\"none\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "\"x\":\"x\",\n",
       "\"y\":\"y\",\n",
       "\"xend\":\"xend\",\n",
       "\"yend\":\"yend\",\n",
       "\"linetype\":\"linetype\"\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"segment\",\n",
       "\"tooltips\":\"none\",\n",
       "\"data\":{\n",
       "}\n",
       "}],\n",
       "\"data_meta\":{\n",
       "\"series_annotations\":[{\n",
       "\"type\":\"int\",\n",
       "\"column\":\"x\"\n",
       "},{\n",
       "\"type\":\"int\",\n",
       "\"column\":\"xend\"\n",
       "}]\n",
       "},\n",
       "\"spec_id\":\"1\"\n",
       "};\n",
       "               window.letsPlotCall(function() {\n",
       "       \n",
       "               var toolbar = null;\n",
       "               var plotContainer = containerDiv;               \n",
       "               \n",
       "                   var options = {\n",
       "                       sizing: {\n",
       "                           width_mode: \"min\",\n",
       "                           height_mode: \"scaled\",\n",
       "                           width: width\n",
       "                       }\n",
       "                   };\n",
       "                   var fig = LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer, options);\n",
       "                   if (toolbar) {\n",
       "                     toolbar.bind(fig);\n",
       "                   }\n",
       "               });\n",
       "               \n",
       "               break;\n",
       "           }\n",
       "       }\n",
       "   });\n",
       "   \n",
       "   observer.observe(containerDiv);\n",
       "   \n",
       "   // ----------\n",
       "   })();\n",
       "   \n",
       "   </script>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val lineTypes = listOf(\n",
    "    listOf(1, 1),               // dotted\n",
    "    listOf(5, 5),               // dashed\n",
    "    listOf(10, 5),              // long dashed\n",
    "    5 to listOf(10, 5),         // long dashed with offset\n",
    "    listOf(5, 10, 1, 10),       // dashdotted\n",
    "    listOf(10, 5, 1, 5, 1, 5),  // dashdotdotted\n",
    ")\n",
    "\n",
    "plotLineTypes(lineTypes)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b704dc2-be36-4e06-924c-76a1be0f257d",
   "metadata": {},
   "source": [
    "#### Use String of HEX Digits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "31971182-b809-4949-a61b-f4cf7cdfefd4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"wqtN6b\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "   \n",
       "   (function() {\n",
       "   // ----------\n",
       "   \n",
       "   var containerDiv = document.getElementById(\"wqtN6b\");\n",
       "   var observer = new ResizeObserver(function(entries) {\n",
       "       for (let entry of entries) {\n",
       "           var width = containerDiv.clientWidth\n",
       "           if (entry.contentBoxSize && width > 0) {\n",
       "           \n",
       "               // Render plot\n",
       "               if (observer) {\n",
       "                   observer.disconnect();\n",
       "                   observer = null;\n",
       "               }\n",
       "\n",
       "               var plotSpec={\n",
       "\"mapping\":{\n",
       "},\n",
       "\"data\":{\n",
       "\"linetype\":[\"11\",\"55\",\"A5\",\"5A1A\"],\n",
       "\"x\":[0.0,0.0,0.0,0.0],\n",
       "\"y\":[\"11\",\"55\",\"A5\",\"5A1A\"],\n",
       "\"yend\":[\"11\",\"55\",\"A5\",\"5A1A\"],\n",
       "\"xend\":[1.0,1.0,1.0,1.0]\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[{\n",
       "\"aesthetic\":\"linetype\",\n",
       "\"discrete\":true,\n",
       "\"scale_mapper_kind\":\"identity\",\n",
       "\"guide\":\"none\"\n",
       "}],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "\"x\":\"x\",\n",
       "\"y\":\"y\",\n",
       "\"xend\":\"xend\",\n",
       "\"yend\":\"yend\",\n",
       "\"linetype\":\"linetype\"\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"segment\",\n",
       "\"tooltips\":\"none\",\n",
       "\"data\":{\n",
       "}\n",
       "}],\n",
       "\"data_meta\":{\n",
       "\"series_annotations\":[{\n",
       "\"type\":\"int\",\n",
       "\"column\":\"x\"\n",
       "},{\n",
       "\"type\":\"int\",\n",
       "\"column\":\"xend\"\n",
       "},{\n",
       "\"type\":\"str\",\n",
       "\"column\":\"y\"\n",
       "},{\n",
       "\"type\":\"str\",\n",
       "\"column\":\"yend\"\n",
       "},{\n",
       "\"type\":\"str\",\n",
       "\"column\":\"linetype\"\n",
       "}]\n",
       "},\n",
       "\"spec_id\":\"2\"\n",
       "};\n",
       "               window.letsPlotCall(function() {\n",
       "       \n",
       "               var toolbar = null;\n",
       "               var plotContainer = containerDiv;               \n",
       "               \n",
       "                   var options = {\n",
       "                       sizing: {\n",
       "                           width_mode: \"min\",\n",
       "                           height_mode: \"scaled\",\n",
       "                           width: width\n",
       "                       }\n",
       "                   };\n",
       "                   var fig = LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer, options);\n",
       "                   if (toolbar) {\n",
       "                     toolbar.bind(fig);\n",
       "                   }\n",
       "               });\n",
       "               \n",
       "               break;\n",
       "           }\n",
       "       }\n",
       "   });\n",
       "   \n",
       "   observer.observe(containerDiv);\n",
       "   \n",
       "   // ----------\n",
       "   })();\n",
       "   \n",
       "   </script>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "val lineTypes = listOf(\n",
    "    \"11\",\n",
    "    \"55\",\n",
    "    \"A5\",\n",
    "    \"5A1A\"\n",
    ")\n",
    "\n",
    "plotLineTypes(lineTypes)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3961346-ea8b-4987-a467-ddb7c01a6d1c",
   "metadata": {},
   "source": [
    "#### Use in `elementLine()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c2defee9-d409-4eb9-ae55-70319bd86b19",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "   <div id=\"CIHBtw\"></div>\n",
       "   <script type=\"text/javascript\" data-lets-plot-script=\"plot\">\n",
       "   \n",
       "   (function() {\n",
       "   // ----------\n",
       "   \n",
       "   var containerDiv = document.getElementById(\"CIHBtw\");\n",
       "   var observer = new ResizeObserver(function(entries) {\n",
       "       for (let entry of entries) {\n",
       "           var width = containerDiv.clientWidth\n",
       "           if (entry.contentBoxSize && width > 0) {\n",
       "           \n",
       "               // Render plot\n",
       "               if (observer) {\n",
       "                   observer.disconnect();\n",
       "                   observer = null;\n",
       "               }\n",
       "\n",
       "               var plotSpec={\n",
       "\"mapping\":{\n",
       "},\n",
       "\"kind\":\"plot\",\n",
       "\"scales\":[],\n",
       "\"layers\":[{\n",
       "\"mapping\":{\n",
       "},\n",
       "\"stat\":\"identity\",\n",
       "\"inherit_aes\":false,\n",
       "\"position\":\"identity\",\n",
       "\"geom\":\"blank\",\n",
       "\"data\":{\n",
       "}\n",
       "}],\n",
       "\"theme\":{\n",
       "\"name\":\"bw\",\n",
       "\"panel_grid\":{\n",
       "\"color\":\"grey\",\n",
       "\"linetype\":[5.0,[10.0,5.0]],\n",
       "\"blank\":false\n",
       "}\n",
       "},\n",
       "\"spec_id\":\"3\"\n",
       "};\n",
       "               window.letsPlotCall(function() {\n",
       "       \n",
       "               var toolbar = null;\n",
       "               var plotContainer = containerDiv;               \n",
       "               \n",
       "                   var options = {\n",
       "                       sizing: {\n",
       "                           width_mode: \"min\",\n",
       "                           height_mode: \"scaled\",\n",
       "                           width: width\n",
       "                       }\n",
       "                   };\n",
       "                   var fig = LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer, options);\n",
       "                   if (toolbar) {\n",
       "                     toolbar.bind(fig);\n",
       "                   }\n",
       "               });\n",
       "               \n",
       "               break;\n",
       "           }\n",
       "       }\n",
       "   });\n",
       "   \n",
       "   observer.observe(containerDiv);\n",
       "   \n",
       "   // ----------\n",
       "   })();\n",
       "   \n",
       "   </script>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "letsPlot() +\n",
    "    geomBlank() + \n",
    "    themeBW() +\n",
    "    theme(panelGrid = elementLine(linetype = 5 to listOf(10, 5), color = \"grey\"))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Kotlin",
   "language": "kotlin",
   "name": "kotlin"
  },
  "language_info": {
   "codemirror_mode": "text/x-kotlin",
   "file_extension": ".kt",
   "mimetype": "text/x-kotlin",
   "name": "kotlin",
   "nbconvert_exporter": "",
   "pygments_lexer": "kotlin",
   "version": "1.9.23"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
